#ifndef COLOR_H_
#define COLOR_H_

#include <algorithm>

using namespace std;

// TODO Possibly complete removal of alpha (is it being used anyhow?)

struct Color
{
	Color(float r = 0.0f, float g = 0.0f, float b = 0.0f, float a = 0.0f)
		:R(r), G(g), B(b), A(a)
	{}

	float R,G,B,A;

	inline void zero()
	{
		R = 0.0f;
		G = 0.0f;
		B = 0.0f;
		A = 0.0f;
	}

	inline void operator += (const Color & c)
	{
		R += c.R;
		G += c.G;
		B += c.B;
		A += c.A;
	}

	/*
	 * WARNING: may lead to some components being less than 0, which is not corrected even if you use
	 * normalize() or normalizeAndScale() (due to performance reasons).
	 */
	inline void operator -= (const Color & c)
	{
		R -= c.R;
		G -= c.G;
		B -= c.B;
		A -= c.A;
	}

	inline void operator *= (float scalar)
	{
		R = R * scalar;
		G = G * scalar;
		B = B * scalar;
		A = A * scalar;
	}

	inline void normalize()
	{
		R = min(1.0f, R);
		G = min(1.0f, G);
		B = min(1.0f, B);
		A = min(1.0f, A);
	}

	inline void normalizeAndScale(float scale)
	{
		R = scale * min(1.0f, R);
		G = scale * min(1.0f, G);
		B = scale * min(1.0f, B);
		A = scale * min(1.0f, A);
	}

	static Color BLACK;
	static Color WHITE;
	static Color RED;
	static Color GREY;
};


inline Color operator + (const Color & c1, const Color & c2)
{
	return Color(
		c1.R + c2.R,
		c1.G + c2.G,
		c1.B + c2.B,
		c1.A + c2.A);
}

/*
 * WARNING: may lead to some components being less than 0, which is not corrected even if you use
 * normalize() or normalizeAndScale() (due to performance reasons).
 */
inline Color operator - (const Color & c1, const Color & c2)
{
	return Color(
		c1.R - c2.R,
		c1.G - c2.G,
		c1.B - c2.B,
		c1.A - c2.A);
}

inline Color operator * (const Color & c1, const Color & c2)
{
	return Color(
		c1.R * c2.R,
		c1.G * c2.G,
		c1.B * c2.B,
		c1.A * c2.A);
}

inline Color operator * (const Color & c1, float scalar)
{
	return Color(
		c1.R * scalar,
		c1.G * scalar,
		c1.B * scalar,
		c1.A * scalar);
}

inline Color operator * (float scalar, const Color & c1)
{
	return Color(
		c1.R * scalar,
		c1.G * scalar,
		c1.B * scalar,
		c1.A * scalar);
}

#endif

